﻿using Bit.Art.Api.Controllers;
using Bit.Art.Core.Extensions;
using Bit.Art.Distributed;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NPOI.HSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Flurl;
using Flurl.Http;

namespace bit.art.test
{
#if UNITTEST
    [TestClass]
    public class 多进程性能测试
    {
        protected static Memcache s_Memcache;

        [ClassInitialize]
        public static void 启动消息队列各个节点(TestContext context)
        {
            var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json");
            var configuration = builder.Build();

            ApplicationLogging.LoggerFactory.AddConsole().AddDebug();
            s_Memcache = Memcache.Create(configuration.GetSection("redis").Value);
        }

        [TestMethod]
        public void 限价单多进程性能测试()
        {
            var controller = new MarketController();
            controller.SetMemcache(s_Memcache);
            var market = "BTC/USDT";

            using (var file = new FileStream("Data\\限价单基本性能测试数据万余条.xls", FileMode.Open, FileAccess.Read))
            {
                var workbook = new HSSFWorkbook(file);
                var sheet = workbook.GetSheetAt(0);
                var rowCount = sheet.LastRowNum;
                for (int ridx = 1; ridx <= rowCount; ridx++)
                {
                    var row = sheet.GetRow(ridx);
                    decimal bidprice, bidvolume, askprice, askvolume;
                    if (row.GetCell(0) != null)
                    {
                        bidprice = Convert.ToDecimal(row.GetCell(0).NumericCellValue);
                        bidvolume = Convert.ToDecimal(row.GetCell(1).NumericCellValue);
                        controller._uid = TestConstants.DEFAULT_BID_USER_ID;
                        Task.Run(async () => await controller.BuyLimit(market, bidprice, bidvolume));
                        Task.Delay(1);
                    }

                    if (row.GetCell(2) != null)
                    {
                        askprice = Convert.ToDecimal(row.GetCell(2).NumericCellValue);
                        askvolume = Convert.ToDecimal(row.GetCell(3).NumericCellValue);
                        controller._uid = TestConstants.DEFAULT_ASK_USER_ID;
                        Task.Run(async () => await controller.SellLimit(market, askprice, askvolume));
                        Task.Delay(1);
                    }
                }
            }

            /*
            var openOrdersResponse = controller.GetOpenOrders("BTC/USDT", TestConstants.DEFAULT_BID_USER_ID).Result;
            Assert.IsTrue(openOrdersResponse.Success);
            var actual = openOrdersResponse.Result;
            Assert.AreEqual(0, actual.Length);
            openOrdersResponse = controller.GetOpenOrders("BTC/USDT", TestConstants.DEFAULT_ASK_USER_ID).Result;
            Assert.IsTrue(openOrdersResponse.Success);
            actual = openOrdersResponse.Result;
            Assert.AreEqual(0, actual.Length);
            */
            System.Threading.Thread.Sleep(1 * 60 * 60 * 1000);
        }

        [TestMethod]
        public void 模拟炒币增值测试()
        {
            var controller = new MarketController();
            controller.SetMemcache(s_Memcache);
            var market = "BTC/USDT";
            int minVolume = 100;//最低成交量
            int maxVolume = 20000;//最高成交量
            var ran = new Random();

            using (StreamReader sr = new StreamReader("Data\\虚拟交易炒币价格测试数据.txt", Encoding.Default))
            {
                var lineValue = sr.ReadLine();
                if (string.IsNullOrEmpty(lineValue))
                    return;
                decimal.TryParse(lineValue, out decimal price);
                if (price <= 0)
                    return;

                //成交量随机
                var volume = ran.Next(minVolume, maxVolume);

                //用户2 下买单
                controller._uid = TestConstants.DEFAULT_BID_USER_ID;
                Task.Run(async () => await controller.BuyLimit(market, price, volume));
                Task.Delay(1);

                //用户1 下卖单
                controller._uid = TestConstants.DEFAULT_ASK_USER_ID;
                Task.Run(async () => await controller.SellLimit(market, price, volume));
                Task.Delay(1);
            }
        }

        [TestMethod]
        public void 模拟炒币远程服务增值测试()
        {
            var accToken = GetToken();
            
            var market = "BTC/USDT";
            int minVolume = 3000;//最低成交量
            int maxVolume = 20000;//最高成交量
            var ran = new Random();

            var buyUrl = "http://exapidev.586886.com/api/Market/BuyLimit";
            var sellUrl = "http://exapidev.586886.com/api/Market/SellLimit";
            using (StreamReader sr = new StreamReader("Data\\虚拟交易炒币价格测试数据.txt", Encoding.Default))
            {
                string lineValue = "";
                do
                {
                    lineValue = sr.ReadLine();
                    if (string.IsNullOrEmpty(lineValue))
                        return;
                    decimal.TryParse(lineValue, out decimal price);
                    if (price <= 0)
                        return;

                    //成交量随机
                    var volume = ran.Next(minVolume, maxVolume);
                    volume = 3000;

                    //用户2 下买单
                    var result1 = buyUrl
                        .WithHeader("Authorization", accToken)
                        .SetQueryParams(new
                        {
                            market,
                            price,
                            quantity = volume
                        })
                        .GetJsonAsync()
                        .Result;
                    Task.Delay(1);

                    //用户1 下卖单
                    var result2 = sellUrl
                        .WithHeader("Authorization", accToken)
                        .SetQueryParams(new
                        {
                            market,
                            price,
                            quantity = volume
                        })
                        .GetJsonAsync()
                        .Result;
                    Task.Delay(1);

                }
                while (!string.IsNullOrEmpty(lineValue));
            }
        }

        private static string GetToken()
        {
            var url1 = "http://exapidev.586886.com/api/ThirdParty/GetAccessToken";
            var result1 = url1.PostJsonAsync(new
            {
                appId = "leyou",
                appSecret = "1eYou@8*93",
                scope = "partner"
            })
            .ReceiveJson()
            .Result;
            var token1 = $"Bearer {result1.result}";

            var url2 = "http://exapidev.586886.com/api/ThirdParty/GetEndUserAccessToken";
            var result2 = url2
                .WithHeader("Authorization", token1)
                .PostJsonAsync(new
                {
                    username = "shiyimin",
                    password = "Pass123$",
                    scope = "market"
                })
                .ReceiveJson()
                .Result;

            var token2 = $"Bearer {result2.result}";
            return token2;
        }
    }
#endif
}
